package ui;

import security.auth.UserManager;
import session.Session;

import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import ui.excute.SQLExecutorHandler;
import ui.excute.UICommandProcessor;
import ui.panel.DatabaseTreePanel;
import ui.panel.MenuBarCreator;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.awt.*;
import java.awt.Font;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据库管理系统的主界面框架
 * 提供SQL编辑、命令执行、数据库浏览等核心功能
 */
public class MainFrame extends JFrame {
    // 单例模式，全局访问点
    public static MainFrame instance;

    // UI组件声明
    public JTextArea consoleArea;          // 输出控制台
    //public JTextField inputField;          // 单行命令输入框
    public JLabel statusLabel;             // 状态栏标签
    public JList<String> dbList;           // 数据库列表
    public JTabbedPane sqlTabbedPane;      // SQL编辑器标签页
    public List<RSyntaxTextArea> sqlEditors = new ArrayList<>(); // SQL编辑器集合
    public DatabaseTreePanel dbTreePanel;  // 数据库树形结构面板
    public long lastExecutionTime = 0;     // 上次SQL执行时间，用于性能统计
    public JTabbedPane resultTabbedPane;   // 结果标签页
    public JToolBar toolBar; // 新增工具栏
    public UIManager.LookAndFeelInfo[] lookAndFeels; // 新增主题信息

    public JTextArea commandInputArea; // 新增命令输入区域
    public JPanel commandPanel; // 新增命令面板
    public boolean isCommandWindowVisible = false; // 命令窗口显示状态



    SQLExecutorHandler sqlExecutorHandler; // 新增SQL执行处理器
    SQLFormatter sqlFormatter; // 新增SQL格式化器
    //SQLCompletion sqlCompletion; // 新增SQL补全器


    public MainFrame(String username) {
        MainFrame.instance = this;


        // 获取当前Session
        Session currentSession = Session.getCurrentSession();
        if (currentSession == null) {
            JOptionPane.showMessageDialog(this, "会话无效，请重新登录", "错误", JOptionPane.ERROR_MESSAGE);
            dispose();
            new LoginFrame();
            return;
        }

        // 设置窗口标题，显示当前用户和权限级别
        int level = currentSession.getUserLevel();
        String levelStr = (level == UserManager.ADMIN_LEVEL) ? "管理员" : "普通用户";
        setTitle("简易 DBMS - 用户: " + username + " (" + levelStr + ")");

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(1000, 800);
        setLocationRelativeTo(null);



        // 初始化UI组件
        MenuBarCreator menuBarCreator = new MenuBarCreator(this);
        setJMenuBar(menuBarCreator.createMenuBar()); // 使用新的菜单栏创建类

        add(createCenterPanel(), BorderLayout.CENTER); // 中央区域布局

        add(createBottomPanel(username), BorderLayout.SOUTH); // 底部区域布局
        bindKeyShortcuts(); // 绑定快捷键

        // 初始化工具栏
        toolBar = createToolBar();
        add(toolBar, BorderLayout.NORTH); // 添加工具栏到窗口顶部

        // 初始化主题信息
        lookAndFeels = UIManager.getInstalledLookAndFeels();

        // 初始化SQL执行处理器
        sqlExecutorHandler = new SQLExecutorHandler(sqlTabbedPane, sqlEditors, consoleArea);

        // 显示窗口并初始化控制台信息
        setVisible(true);
        consoleArea.append("欢迎使用简易 DBMS！\n输入 SQL 或系统命令开始操作。\n\n");
    }


    // 显示或隐藏命令窗口
    public void toggleCommandWindow() {
        isCommandWindowVisible = !isCommandWindowVisible;
        commandPanel.setVisible(isCommandWindowVisible);
        // 移除 pack() 方法
        // 强制重新验证布局并重绘
        revalidate();
        repaint();
    }

    // 执行命令输入区域的命令
    public void executeCommandFromWindow() {
        String command = commandInputArea.getText().trim();
        if (!command.isEmpty()) {
            consoleArea.append("\n> " + command + "\n");
            executeCommand(command);
            commandInputArea.setText(""); // 清空输入框
        }
    }


    /**
     * 创建中央面板区域，包含数据库树和SQL编辑器/控制台
     */
    public JPanel createCenterPanel() {
        // 初始化数据库树形面板
        dbTreePanel = new DatabaseTreePanel();

        // 初始化SQL编辑器标签页
        sqlTabbedPane = new JTabbedPane();
        sqlTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);

        // 添加右键菜单支持
        sqlTabbedPane.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                int index = sqlTabbedPane.indexAtLocation(e.getX(), e.getY());
                if (index != -1 && SwingUtilities.isRightMouseButton(e)) {
                    JPopupMenu menu = new JPopupMenu();

                    JMenuItem renameItem = new JMenuItem("重命名标签页");
                    renameItem.addActionListener(ev -> {
                        String newName = JOptionPane.showInputDialog("输入新的标签页名称:",
                                sqlTabbedPane.getTitleAt(index));
                        if (newName != null && !newName.trim().isEmpty()) {
                            sqlTabbedPane.setTitleAt(index, newName.trim());
                        }
                    });
                    menu.add(renameItem);

                    JMenuItem closeItem = new JMenuItem("关闭标签页");
                    closeItem.addActionListener(ev -> closeTab(index));
                    menu.add(closeItem);

                    JMenuItem closeOthersItem = new JMenuItem("关闭其他标签页");
                    closeOthersItem.addActionListener(ev -> closeOtherTabs(index));
                    menu.add(closeOthersItem);

                    menu.add(new JSeparator());

                    JMenuItem saveItem = new JMenuItem("保存");
                    saveItem.addActionListener(ev -> saveSQLToFile());
                    menu.add(saveItem);

                    menu.show(sqlTabbedPane, e.getX(), e.getY());
                }
            }
        });

        // 添加默认的SQL编辑标签页
        addNewTab();

        // 初始化输出控制台
        consoleArea = new JTextArea(10, 40);
        consoleArea.setEditable(false);
        consoleArea.setLineWrap(true);
        consoleArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 13));

        // 添加行号支持
        JScrollPane consoleScroll = new JScrollPane(consoleArea);
        consoleScroll.setBorder(BorderFactory.createTitledBorder("输出控制台"));

        // 初始化结果标签页
        resultTabbedPane = new JTabbedPane();
        resultTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);

        // 创建合并的标签页
        JTabbedPane combinedTabbedPane = new JTabbedPane();
        combinedTabbedPane.addTab("控制台", consoleScroll);
        combinedTabbedPane.addTab("查询结果", resultTabbedPane);

        // 使用分割面板分隔编辑器和合并后的标签页
        JSplitPane editorResultSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, sqlTabbedPane, combinedTabbedPane);
        editorResultSplit.setResizeWeight(0.6); // 设置分割比例
        editorResultSplit.setDividerLocation(400); // 初始分割位置
        editorResultSplit.setContinuousLayout(true); // 连续布局

        // 右侧面板包含编辑器和合并后的标签页
        JPanel rightPanel = new JPanel(new BorderLayout());
        rightPanel.add(editorResultSplit, BorderLayout.CENTER);

        // 使用分割面板分隔数据库树和右侧内容
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, dbTreePanel, rightPanel);
        splitPane.setDividerLocation(220); // 初始分割位置
        splitPane.setContinuousLayout(true); // 连续布局

        return new JPanel(new BorderLayout()) {{
            add(splitPane);
        }};
    }

    /**
     * 创建底部面板，包含状态栏和命令输入区域
     */
    public JPanel createBottomPanel(String username) {
        JPanel bottomPanel = new JPanel(new BorderLayout());

        // 状态栏
        statusLabel = new JLabel();
        statusLabel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
        statusLabel.setFont(new Font("Arial", Font.PLAIN, 12));
        updateStatusBar();

        bottomPanel.add(statusLabel, BorderLayout.SOUTH);

        // 初始化命令输入区域
        commandInputArea = new JTextArea(5, 40);
        commandInputArea.setLineWrap(true);
        JScrollPane commandScroll = new JScrollPane(commandInputArea);
        // 使用类成员变量 commandPanel
        commandPanel = new JPanel(new BorderLayout());
        commandPanel.add(commandScroll, BorderLayout.CENTER);
        commandPanel.setVisible(false); // 初始隐藏

        // 为命令输入区域添加键盘事件监听器
        commandInputArea.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER && !e.isShiftDown()) {
                    e.consume(); // 阻止换行
                    String command = commandInputArea.getText().trim();
                    if (!command.isEmpty()) {
                        // 在控制台显示命令前缀
                        consoleArea.append("> " + command + "\n");
                        // 执行命令
                        executeCommand(command);
                        // 清空输入框
                        commandInputArea.setText("");
                    }
                }
            }
        });

        // 将命令面板添加到底部面板
        bottomPanel.add(commandPanel, BorderLayout.NORTH);

        return bottomPanel;
    }

    /**
     * 处理从输入框提交的命令
     */
    public void handleCommand(ActionEvent e) {
        String command = commandInputArea.getText().trim();
        if (command.isEmpty()) return;

        consoleArea.append("\n> " + command + "\n");
        commandInputArea.setText("");

        executeCommand(command);
    }

    /**
     * 执行SQL或系统命令
     * @param command 要执行的命令
     */
    public void executeCommand(String command) {
        if (command == null || command.trim().isEmpty()) return;

        command = command.trim();
        long startTime = System.currentTimeMillis();

        try {
            // 使用正确的UICommandProcessor.process方法
            Object result = UICommandProcessor.process(command);
            lastExecutionTime = System.currentTimeMillis() - startTime;
            handleSQLExecutionResult(result, command);
            
            refreshAllUi(); // 执行命令后刷新所有UI元素
        } catch (Exception ex) {
            consoleArea.append("执行出错: " + ex.getMessage() + "\n");
            logError("SQL执行错误", ex);
            updateStatusBar(); // Update status even on error
        }
    }

    /**
     * 执行当前SQL编辑器中的SQL
     */
    public void executeSQL() {
        sqlExecutorHandler.executeSQL();
        updateStatusBar();
        refreshAllUi(); // 执行SQL后刷新所有UI元素
    }

    /**
     * 刷新所有UI元素
     * 用于在执行SQL后更新数据显示
     */
    public void refreshAllUi() {
        // 刷新数据库列表
        refreshDatabaseList();
        
        // 强制刷新控制台
        consoleArea.setCaretPosition(consoleArea.getDocument().getLength());
        consoleArea.update(consoleArea.getGraphics());
        
        // 刷新结果显示
        if (resultTabbedPane != null && resultTabbedPane.getTabCount() > 0) {
            for (int i = 0; i < resultTabbedPane.getTabCount(); i++) {
                Component component = resultTabbedPane.getComponentAt(i);
                if (component != null) {
                    component.validate();
                    component.repaint();
                }
            }
            resultTabbedPane.validate();
            resultTabbedPane.repaint();
        }
        
        // 更新整个UI
        SwingUtilities.updateComponentTreeUI(this);
    }

    /**
     * 执行选中的SQL文本
     */
    public void executeSelectedSQL() {
        int index = sqlTabbedPane.getSelectedIndex();
        if (index == -1 || index >= sqlEditors.size()) return;

        RSyntaxTextArea editor = sqlEditors.get(index);
        String selectedText = editor.getSelectedText();

        if (selectedText != null && !selectedText.trim().isEmpty()) {
            consoleArea.append("\n> " + selectedText.trim() + "\n");
            executeCommand(selectedText);
            refreshAllUi(); // 执行SQL后刷新所有UI元素
        } else {
            // 如果没有选中文本，执行整个编辑器内容
            executeSQL();
        }
    }

    /**
     * 执行当前SQL并自动提交事务
     */
    public void executeAndCommit() {
        sqlExecutorHandler.executeAndCommit();
        refreshAllUi(); // 执行SQL后刷新所有UI元素
    }

    /**
     * 更新状态栏信息，显示当前用户和数据库
     */
    public void updateStatusBar() {
        String username = Session.getCurrentUser();
        String currentDB = UICommandProcessor.getCurrentDatabase();
        String status = "当前用户: " + username + " | 当前数据库: " + (currentDB != null ? currentDB : "[未选择]");

        // 添加执行时间信息
        if (lastExecutionTime > 0) {
            status += " | 上次执行: " + lastExecutionTime + "ms";
        }

        // 设置支持中文的字体
        statusLabel.setFont(new Font("宋体", Font.PLAIN, 12));
        statusLabel.setText(status);
    }

    /**
     * 刷新数据库列表
     */
    public void refreshDatabaseList() {
        // 使用SwingWorker在后台线程刷新数据库列表，避免阻塞UI
        SwingWorker<List<String>, Void> worker = new SwingWorker<List<String>, Void>() {
            @Override
            protected List<String> doInBackground() throws Exception {
                return UICommandProcessor.getAllDatabases();
            }

            @Override
            protected void done() {
                try {
                    if (dbList != null) {
                        DefaultListModel<String> model = new DefaultListModel<>();
                        List<String> dbs = get();
                        for (String db : dbs) {
                            model.addElement(db);
                        }
                        dbList.setModel(model);
                    }
                    
                    // 同时刷新数据库树面板
                    if (dbTreePanel != null) {
                        dbTreePanel.refreshTree();
                        System.out.println("数据库树结构已刷新");
                    }
                } catch (Exception ex) {
                    logError("刷新数据库列表失败", ex);
                }
            }
        };

        worker.execute();
    }

    /**
     * 绑定快捷键
     */
    public void bindKeyShortcuts() {
        // 为SQL执行绑定Ctrl+Enter快捷键
        InputMap im = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap am = getRootPane().getActionMap();

        // 执行SQL
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.CTRL_DOWN_MASK), "executeSQL");
        am.put("executeSQL", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                executeSQL();
            }
        });

        // 新建标签页
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK), "newTab");
        am.put("newTab", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addNewTab();
            }
        });

        // 关闭当前标签页
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK), "closeTab");
        am.put("closeTab", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int selectedIndex = sqlTabbedPane.getSelectedIndex();
                if (selectedIndex >= 0) {
                    closeTab(selectedIndex);
                }
            }
        });
    }

    /**
     * 打开SQL文件
     */
    public void openSQLFile() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new FileNameExtensionFilter("SQL 文件", "sql"));
        fileChooser.setDialogTitle("打开 SQL 文件");

        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();
            try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
                // 添加新标签页并读取文件内容
                addNewTab();
                RSyntaxTextArea editor = sqlEditors.get(sqlEditors.size() - 1);
                editor.read(reader, null);

                // 设置标签页标题为文件名
                sqlTabbedPane.setTitleAt(sqlTabbedPane.getTabCount() - 1, file.getName());

                // 记录文件路径，用于保存时默认路径
                editor.putClientProperty("filePath", file.getAbsolutePath());

                consoleArea.append("已打开文件: " + file.getName() + "\n");
            } catch (IOException e) {
                showErrorDialog("打开文件失败", "无法读取文件: " + e.getMessage());
            }
        }
    }

    /**
     * 保存SQL到文件
     */
    public void saveSQLToFile() {
        saveSQLToFile(false); // 默认不强制显示保存对话框
    }

    /**
     * 保存SQL到文件的重载方法
     * @param forceSaveAs 是否强制显示保存对话框
     */
    public void saveSQLToFile(boolean forceSaveAs) {
        int index = sqlTabbedPane.getSelectedIndex();
        if (index == -1 || index >= sqlEditors.size()) return;

        RSyntaxTextArea editor = sqlEditors.get(index);
        String defaultName = sqlTabbedPane.getTitleAt(index);

        // 如果已有文件路径且不是强制另存为，则直接保存
        if (!forceSaveAs) {
            String filePath = (String) editor.getClientProperty("filePath");
            if (filePath != null) {
                try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
                    editor.write(writer);
                    consoleArea.append("已保存文件: " + new File(filePath).getName() + "\n");
                    return;
                } catch (IOException e) {
                    showErrorDialog("保存文件失败", "无法写入文件: " + e.getMessage());
                }
            }
        }

        // 显示保存对话框
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setSelectedFile(new File(defaultName.endsWith(".sql") ? defaultName : defaultName + ".sql"));
        fileChooser.setFileFilter(new FileNameExtensionFilter("SQL 文件", "sql"));
        fileChooser.setDialogTitle("保存 SQL 文件");

        int result = fileChooser.showSaveDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();

            // 确保文件扩展名为.sql
            String fileName = file.getName();
            if (!fileName.toLowerCase().endsWith(".sql")) {
                file = new File(file.getParentFile(), fileName + ".sql");
            }

            try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
                editor.write(writer);
                sqlTabbedPane.setTitleAt(index, file.getName());
                editor.putClientProperty("filePath", file.getAbsolutePath());
                consoleArea.append("已保存文件: " + file.getName() + "\n");
            } catch (IOException e) {
                showErrorDialog("保存文件失败", "无法写入文件: " + e.getMessage());
            }
        }
    }

    /**
     * 添加新的SQL编辑标签页
     */
    public void addNewTab() {
        RSyntaxTextArea newEditor = new RSyntaxTextArea(15, 60);
        newEditor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_SQL);
        newEditor.setCodeFoldingEnabled(true);
        newEditor.setAntiAliasingEnabled(true);
        newEditor.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 14));
        newEditor.setTabsEmulated(true);
        newEditor.setTabSize(4);

        // 添加文本改变监听器，用于标记标签页是否修改
        newEditor.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                markTabAsModified();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                markTabAsModified();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                markTabAsModified();
            }

            public void markTabAsModified() {
                int index = sqlTabbedPane.getSelectedIndex();
                if (index >= 0) {
                    String title = sqlTabbedPane.getTitleAt(index);
                    if (!title.endsWith("*") && !title.contains("[新文件]")) {
                        sqlTabbedPane.setTitleAt(index, title + "*");
                    }
                }
            }
        });

        sqlEditors.add(newEditor);
        sqlTabbedPane.addTab("SQL " + sqlEditors.size(), new RTextScrollPane(newEditor));
        sqlTabbedPane.setSelectedIndex(sqlTabbedPane.getTabCount() - 1);
    }

    /**
     * 关闭指定索引的标签页
     */
    public void closeTab(int index) {
        // 检查是否需要保存
        String title = sqlTabbedPane.getTitleAt(index);
        if (title.endsWith("*")) {
            int result = JOptionPane.showConfirmDialog(
                    this,
                    "是否保存更改到 " + title + "?",
                    "保存确认",
                    JOptionPane.YES_NO_CANCEL_OPTION
            );

            if (result == JOptionPane.YES_OPTION) {
                saveSQLToFile();
            } else if (result == JOptionPane.CANCEL_OPTION) {
                return; // 取消关闭操作
            }
        }

        sqlEditors.remove(index);
        sqlTabbedPane.removeTabAt(index);
    }

    /**
     * 关闭除指定索引外的其他标签页
     */
    public void closeOtherTabs(int index) {
        // 从后往前关闭标签页，避免索引变化
        for (int i = sqlTabbedPane.getTabCount() - 1; i >= 0; i--) {
            if (i != index) {
                closeTab(i);
            }
        }
    }

    /**
     * 格式化当前SQL编辑器中的SQL代码
     */
    public void formatSQL() {
        int index = sqlTabbedPane.getSelectedIndex();
        if (index == -1 || index >= sqlEditors.size()) return;

        RSyntaxTextArea editor = sqlEditors.get(index);
        String sql = editor.getText();

        try {
            // 这里应该调用SQL格式化工具，示例中仅做简单缩进处理
            String formattedSQL = formatSQLText(sql);
            editor.setText(formattedSQL);

            consoleArea.append("SQL 已格式化\n");
        } catch (Exception e) {
            consoleArea.append("格式化失败: " + e.getMessage() + "\n");
        }
    }

    /**
     * 简单的SQL格式化实现
     */
    public String formatSQLText(String sql) {
        return sqlFormatter.formatSQLText(sql);
    }

    /**
     * 显示查找替换对话框
     */
    public void showFindReplaceDialog() {
        // 这里应该实现一个查找替换对话框
        JOptionPane.showMessageDialog(this,
                "查找替换功能将在未来版本中实现",
                "功能待实现",
                JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * 显示关于对话框
     */
    public void showAboutDialog() {
        Session currentSession = Session.getCurrentSession();
        String username = currentSession != null ? currentSession.getUsername() : "未登录";
        int level = currentSession != null ? currentSession.getUserLevel() : -1;
        String levelStr = level == UserManager.ADMIN_LEVEL ? "管理员" :
                         level == UserManager.NORMAL_LEVEL ? "普通用户" : "未登录";

        JTextArea aboutText = new JTextArea(
                "简易 DBMS 客户端\n\n" +
                "版本: 1.0.0\n" +
                "当前用户: " + username + " (" + levelStr + ")\n" +
                "基于 Java Swing 开发\n\n" +
                "支持 SQL 编辑、执行和数据库管理功能"
        );
        aboutText.setEditable(false);
        aboutText.setOpaque(false);

        JOptionPane.showMessageDialog(
                this,
                aboutText,
                "关于",
                JOptionPane.INFORMATION_MESSAGE
        );
    }

    /**
     * 显示快捷键帮助对话框
     */
    public void showShortcutDialog() {
        JTextArea shortcutsText = new JTextArea(
                "常用快捷键:\n\n" +
                        "Ctrl+Enter      - 执行 SQL\n" +
                        "Ctrl+T          - 新建标签页\n" +
                        "Ctrl+W          - 关闭当前标签页\n" +
                        "Ctrl+S          - 保存当前标签页\n" +
                        "Ctrl+F          - 查找/替换\n\n" +
                        "更多功能请查看菜单"
        );
        shortcutsText.setEditable(false);
        shortcutsText.setOpaque(false);

        JOptionPane.showMessageDialog(
                this,
                shortcutsText,
                "快捷键帮助",
                JOptionPane.INFORMATION_MESSAGE
        );
    }

    /**
     * 显示文档
     */
    public void showDocumentation() {
        // 这里应该打开文档或显示帮助信息
        JOptionPane.showMessageDialog(this,
                "文档将在未来版本中提供",
                "文档",
                JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * 连接数据库操作
     */
    public void connectDatabase() {
        // 这里应该实现数据库连接对话框
        String url = JOptionPane.showInputDialog(this, "请输入数据库连接URL:", "jdbc:mysql://localhost:3306/");
        if (url == null || url.trim().isEmpty()) return;

        String username = JOptionPane.showInputDialog(this, "请输入用户名:", "root");
        if (username == null || username.trim().isEmpty()) return;

        String password = JOptionPane.showInputDialog(this, "请输入密码:", "");

        try {
            // 调用数据库连接逻辑
            boolean connected = UICommandProcessor.connect(url, username, password);
            if (connected) {
                consoleArea.append("已成功连接到数据库: " + url + "\n");
                refreshDatabaseList();
                dbTreePanel.refreshTree();
                updateStatusBar();  // 确保状态栏立即更新
                SwingUtilities.invokeLater(() -> updateStatusBar());  // 在EDT线程再次确保更新
            } else {
                consoleArea.append("连接失败，请检查URL、用户名和密码\n");
            }
        } catch (Exception e) {
            consoleArea.append("连接错误: " + e.getMessage() + "\n");
            logError("数据库连接失败", e);
        }
    }

    /**
     * 切换数据库操作
     */
    public void switchDatabase() {
        // 获取可用数据库列表
        List<String> databases = UICommandProcessor.getAllDatabases();
        if (databases == null || databases.isEmpty()) {
            consoleArea.append("没有可用的数据库\n");
            return;
        }

        // 显示选择对话框
        String[] dbArray = databases.toArray(new String[0]);
        String selectedDB = (String) JOptionPane.showInputDialog(
                this,
                "选择要切换的数据库:",
                "切换数据库",
                JOptionPane.QUESTION_MESSAGE,
                null,
                dbArray,
                dbArray[0]
        );

        if (selectedDB != null) {
            try {
                boolean switched = UICommandProcessor.useDatabase(selectedDB);
                if (switched) {
                consoleArea.append("已成功切换到数据库: " + selectedDB + "\n");
                refreshDatabaseList();
                dbTreePanel.refreshTree();
                updateStatusBar();  // 确保状态栏立即更新
                SwingUtilities.invokeLater(() -> updateStatusBar());  // 在EDT线程再次确保更新
            } else {
                consoleArea.append("切换失败，请检查数据库名称\n");
            }
            } catch (Exception e) {
                consoleArea.append("切换错误: " + e.getMessage() + "\n");
                logError("数据库切换失败", e);
            }
        }
    }

    /**
     * 显示查询结果
     */
    public void showQueryResult(String command, ArrayList<ArrayList<String>> results) {
        if (results == null || results.isEmpty()) {
            return;
        }

        try {
            // 创建表格模型
            DefaultTableModel model = new DefaultTableModel();

            // 添加表头
            ArrayList<String> headers = results.get(0);
            for (String header : headers) {
                model.addColumn(header);
            }

            // 添加数据行
            for (int i = 1; i < results.size(); i++) {
                ArrayList<String> row = results.get(i);
                model.addRow(row.toArray());
            }

            // 创建表格
            JTable table = new JTable(model);
            table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
            table.setFillsViewportHeight(true);

            // 添加右键菜单
            JPopupMenu popupMenu = new JPopupMenu();
            JMenuItem exportExcelItem = new JMenuItem("导出Excel");
            exportExcelItem.addActionListener(e -> {
                JFileChooser fileChooser = new JFileChooser();
                fileChooser.setFileFilter(new FileNameExtensionFilter("Excel文件", "xlsx"));
                if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
                    File file = fileChooser.getSelectedFile();
                    if (!file.getName().toLowerCase().endsWith(".xlsx")) {
                        file = new File(file.getAbsolutePath() + ".xlsx");
                    }
                    try {
                        exportToExcel(table, file);
                        consoleArea.append("已导出Excel文件: " + file.getName() + "\n");
                    } catch (Exception ex) {
                        consoleArea.append("导出Excel失败: " + ex.getMessage() + "\n");
                    }
                }
            });
            popupMenu.add(exportExcelItem);
            table.setComponentPopupMenu(popupMenu);

            // 添加表格到结果面板
            JScrollPane scrollPane = new JScrollPane(table);
            scrollPane.setBorder(BorderFactory.createTitledBorder("查询结果 - " + command));

            // 添加到结果标签页并设置可关闭
            resultTabbedPane.addTab("查询结果", scrollPane);
            resultTabbedPane.setTabComponentAt(resultTabbedPane.getTabCount() - 1,
                createTabHeader("查询结果", resultTabbedPane));
            resultTabbedPane.setSelectedIndex(resultTabbedPane.getTabCount() - 1);
        } catch (Exception e) {
            consoleArea.append("显示查询结果出错: " + e.getMessage() + "\n");
        }
    }

    public void showQueryResultFromString(String command ,String result) {
        if (result == null || result.trim().isEmpty()) {
            consoleArea.append("查询结果为空\n");
            return;
        }

        // 去除"查询结果:"部分以及"执行时间"部分
        String[] lines = result.split("\n");

        // 找到查询结果的开始行，表头在第二行
        int startIdx = 1;
        for (int i = 0; i < lines.length; i++) {
            if (lines[i].trim().startsWith("查询结果:")) {
                startIdx = i + 1; // 表头是第二行
                break;
            }
        }

        // 如果没有找到查询结果的开始行，返回
        if (startIdx == -1 || startIdx >= lines.length) {
            consoleArea.append("查询结果格式错误: 没有找到表头\n");
            return;
        }

        // 获取列头
        String[] headers = lines[startIdx].split("\t");
        ArrayList<String> headerList = new ArrayList<>();
        for (String header : headers) {
            headerList.add(header.trim());
        }

        // 创建数据存储结构
        ArrayList<ArrayList<String>> results = new ArrayList<>();
        results.add(headerList);

        // 处理数据行
        for (int i = startIdx + 1; i < lines.length - 1; i++) {  // 排除最后一行执行时间
            String line = lines[i].trim();
            if (line.isEmpty()) {
                continue;  // 跳过空行
            }

            String[] data = line.split("\t");
            ArrayList<String> row = new ArrayList<>();
            for (String cell : data) {
                row.add(cell.trim());
            }
            results.add(row);
        }

        // 执行时间在最后一行，我们可以忽略
        String executionTime = lines[lines.length - 1].trim();
        if (executionTime.startsWith("执行时间:")) {
            // 可以打印或做其他处理
            consoleArea.append("执行时间: " + executionTime + "\n");
        }

        // 调用显示查询结果的方法
        showQueryResult(command, results);
    }







    /**
     * 显示表结构信息
     * @param tableInfo 表结构信息列表，每行包含列名、类型、是否可为空等
     * @param tableTitle 表标题（格式：dbName.tableName）
     */
    /**
     * 创建带关闭按钮的标签页标题
     */
    private JPanel createTabHeader(String title, JTabbedPane tabbedPane) {
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        panel.setOpaque(false);

        JLabel label = new JLabel(title);
        JButton closeButton = new JButton("×");
        closeButton.setBorder(BorderFactory.createEmptyBorder());
        closeButton.setContentAreaFilled(false);
        closeButton.addActionListener(e -> {
            int index = tabbedPane.indexOfTabComponent(panel);
            if (index != -1) {
                tabbedPane.remove(index);
            }
        });

        panel.add(label);
        panel.add(Box.createHorizontalStrut(5));
        panel.add(closeButton);

        return panel;
    }

    /**
     * 导出表格数据到Excel文件
     */
    private void exportToExcel(JTable table, File file) throws Exception {
        DefaultTableModel model = (DefaultTableModel) table.getModel();

        // 创建工作簿和工作表
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("查询结果");

        // 创建表头行
        Row headerRow = sheet.createRow(0);
        for (int col = 0; col < model.getColumnCount(); col++) {
            Cell cell = headerRow.createCell(col);
            cell.setCellValue(model.getColumnName(col));
        }

        // 填充数据行
        for (int row = 0; row < model.getRowCount(); row++) {
            Row dataRow = sheet.createRow(row + 1);
            for (int col = 0; col < model.getColumnCount(); col++) {
                Object value = model.getValueAt(row, col);
                Cell cell = dataRow.createCell(col);
                if (value != null) {
                    cell.setCellValue(value.toString());
                }
            }
        }

        // 自动调整列宽
        for (int col = 0; col < model.getColumnCount(); col++) {
            sheet.autoSizeColumn(col);
        }

        // 写入文件
        try (FileOutputStream fos = new FileOutputStream(file)) {
            workbook.write(fos);
        }

        workbook.close();
    }

    public void showTableInfo(List<String[]> tableInfo, String tableTitle) {
        // Create a more descriptive title if it's just the command
        String finalTableTitle = tableTitle;
        if (tableTitle.toUpperCase().startsWith("DESC")){
            finalTableTitle = "表结构: " + tableTitle.substring(tableTitle.indexOf(" ")).trim();
        }

        // 创建表格模型
        DefaultTableModel model = new DefaultTableModel();
        model.addColumn("列名");
        model.addColumn("类型");
        model.addColumn("是否可为空");
        model.addColumn("默认值");
        model.addColumn("主键");
        model.addColumn("是否唯一");
        model.addColumn("外键");
        model.addColumn("CHECK约束");

        // 添加数据
        for (String[] row : tableInfo) {
            // 如果原始数据没有足够列，则扩展以支持新增约束列
            String[] extendedRow = new String[8]; // 增加到8列
            
            // 复制原始数据
            for(int i = 0; i < Math.min(row.length, extendedRow.length); i++) {
                extendedRow[i] = row[i];
            }
            
            // 添加默认值到新增列
            for(int i = row.length; i < extendedRow.length; i++) {
                extendedRow[i] = "否";
            }
            
            model.addRow(extendedRow);
        }

        // 创建表格
        JTable table = new JTable(model);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        table.setFillsViewportHeight(true);

        // 添加表格到结果面板
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setBorder(BorderFactory.createTitledBorder(finalTableTitle));

        resultTabbedPane.addTab("表结构: " + finalTableTitle, scrollPane);
        resultTabbedPane.setTabComponentAt(resultTabbedPane.getTabCount() - 1, 
            createTabHeader("表结构: " + finalTableTitle, resultTabbedPane));

        resultTabbedPane.setSelectedIndex(resultTabbedPane.getTabCount() - 1);
        // Ensure the parent "查询结果" tab is selected
        // This requires combinedTabbedPane to be a field, which was done in a previous step.
        // If createCenterPanel makes combinedTabbedPane local, this won't work directly.
        // Assuming combinedTabbedPane is a field:
        // this.combinedTabbedPane.setSelectedComponent(this.resultTabbedPane);
        // More robust way to get to the JTabbedPane containing resultTabbedPane:
        if (this.resultTabbedPane.getParent() instanceof JTabbedPane) {
            JTabbedPane parentTabbedPane = (JTabbedPane) this.resultTabbedPane.getParent();
            parentTabbedPane.setSelectedComponent(this.resultTabbedPane);
        } else {
            System.out.println("[MainFrame.showTableInfo] resultTabbedPane parent is not JTabbedPane, cannot auto-select parent tab.");
        }
    }

    /**
     * 显示错误对话框
     */
    public void showErrorDialog(String title, String message) {
        JOptionPane.showMessageDialog(this, message, title, JOptionPane.ERROR_MESSAGE);
    }

    /**
     * 记录错误日志
     */
    public void logError(String message, Exception ex) {
        System.err.println(message + ": " + ex.getMessage());
        ex.printStackTrace();
    }

    /**
     * 创建工具栏
     */
    public JToolBar createToolBar() {
        JToolBar toolBar = new JToolBar();
        toolBar.setFloatable(false);

        // 新建标签页按钮
        JButton newTabButton = new JButton(new ImageIcon("path/to/newtab_icon.png"));
        newTabButton.setToolTipText("新建标签页");
        newTabButton.addActionListener(e -> addNewTab());
        toolBar.add(newTabButton);

        // 打开文件按钮
        JButton openButton = new JButton(new ImageIcon("path/to/open_icon.png"));
        openButton.setToolTipText("打开文件");
        openButton.addActionListener(e -> openSQLFile());
        toolBar.add(openButton);

        // 保存文件按钮
        JButton saveButton = new JButton(new ImageIcon("path/to/save_icon.png"));
        saveButton.setToolTipText("保存文件");
        saveButton.addActionListener(e -> saveSQLToFile());
        toolBar.add(saveButton);

        // 执行 SQL 按钮
        JButton executeButton = new JButton(new ImageIcon("path/to/execute_icon.png"));
        executeButton.setToolTipText("执行 SQL");
        executeButton.addActionListener(e -> executeSQL());
        toolBar.add(executeButton);

        // 主题切换按钮
        JButton themeButton = new JButton("主题");
        themeButton.addActionListener(new ActionListener() {
            int currentThemeIndex = 0;
            @Override
            public void actionPerformed(ActionEvent e) {
                currentThemeIndex = (currentThemeIndex + 1) % lookAndFeels.length;
                try {
                    UIManager.setLookAndFeel(lookAndFeels[currentThemeIndex].getClassName());
                    SwingUtilities.updateComponentTreeUI(MainFrame.this);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
        toolBar.add(themeButton);

        return toolBar;
    }



    // 为了能访问这些方法，需要添加对应的 getter 方法
    public JTabbedPane getSqlTabbedPane() {
        return sqlTabbedPane;
    }

    public List<RSyntaxTextArea> getSqlEditors() {
        return sqlEditors;
    }

    // Helper method to check if the result is an error list from DataManager
    private boolean isErrorStringList(Object obj) {
        if (obj instanceof List) {
            List<?> list = (List<?>) obj;
            if (!list.isEmpty() && list.get(0) instanceof String[]) {
                String[] firstRow = (String[]) list.get(0);
                // Check if the first column of the first row is "ERROR"
                if (firstRow.length > 0 && "ERROR".equals(firstRow[0])) {
                    return true;
                }
            }
        }
        return false;
    }

    // Helper method to extract table name for DESCRIBE results title
    private String extractTableNameFromDescribe(String describeCommand, String currentDbName, String currentOwner) {
        String[] parts = describeCommand.trim().toUpperCase().split("\\s+");
        String tableNameOnly = null;
        if (parts.length > 1 && (parts[0].equals("DESC") || parts[0].equals("DESCRIBE"))) {
            tableNameOnly = parts[1].replace(";", "");
        }

        if (tableNameOnly != null) {
            // Prefer fully qualified name if possible, otherwise just the table name
            if (currentDbName != null && !currentDbName.isEmpty() && currentOwner != null && !currentOwner.isEmpty()) {
                return currentOwner + "." + currentDbName + "." + tableNameOnly;
            } else if (currentDbName != null && !currentDbName.isEmpty()) {
                return currentDbName + "." + tableNameOnly;
            }
            return tableNameOnly;
        }
        return describeCommand; // Fallback to the full command if parsing fails
    }
    
    // Helper method to ensure the correct tab in resultTabbedPane is selected
    private void selectResultTab(String titlePrefix) {
        for (int i = 0; i < resultTabbedPane.getTabCount(); i++) {
            Component tabComponent = resultTabbedPane.getTabComponentAt(i);
            String tabTitle = "";
            if (tabComponent instanceof JPanel) { // Our custom tab header is a JPanel
                for (Component subComp : ((JPanel) tabComponent).getComponents()) {
                    if (subComp instanceof JLabel) {
                        tabTitle = ((JLabel) subComp).getText();
                        break;
                    }
                }
            } else {
                 tabTitle = resultTabbedPane.getTitleAt(i); // Fallback if not custom header
            }

            if (tabTitle.startsWith(titlePrefix)) {
                resultTabbedPane.setSelectedIndex(i);
                // Also ensure the "查询结果" tab itself is selected in the combinedTabbedPane
                // combinedTabbedPane.setSelectedComponent(resultTabbedPane); // This needs combinedTabbedPane to be a field
                // Assuming combinedTabbedPane is a field or accessible for this selection:
                // This part was added in a previous step, ensure combinedTabbedPane is a field.
                // If combinedTabbedPane is `this.combinedTabbedPane`
                // this.combinedTabbedPane.setSelectedComponent(resultTabbedPane);
                // This line depends on combinedTabbedPane being accessible. It might be a local var in createCenterPanel.
                // For now, focusing on resultTabbedPane internal selection.
                // To select the parent tab: locate combinedTabbedPane and call setSelectedComponent.
                // This requires combinedTabbedPane to be a class field.
                // Let's assume it is for now, as per prior refactoring for DESCRIBE display.
                if (this.resultTabbedPane.getParent() instanceof JTabbedPane) {
                    JTabbedPane parentTabbedPane = (JTabbedPane) this.resultTabbedPane.getParent();
                    parentTabbedPane.setSelectedComponent(this.resultTabbedPane);
                }
                return;
            }
        }
    }

    public void handleSQLExecutionResult(Object resultObj, String command) {
        Session session = Session.getCurrentSession(); // Get current session for context

        if (isErrorStringList(resultObj)) { // Check first if it's a DataManager error list
            List<String[]> errorList = (List<String[]>) resultObj;
            String errorMessage = "Error from data layer: ";
            if (!errorList.isEmpty() && errorList.get(0).length > 1) {
                errorMessage += errorList.get(0)[1]; // The actual error message from DataManager
            }
            consoleArea.append("❌ " + errorMessage + "\n");
            consoleArea.append("执行完成，耗时: " + lastExecutionTime + "ms\n");
        }
        // Check for SELECT results (ArrayList of ArrayList of String)
        else if (resultObj instanceof ArrayList && 
                 !((ArrayList<?>) resultObj).isEmpty() && 
                 ((ArrayList<?>) resultObj).get(0) instanceof ArrayList && 
                 !((ArrayList<?>)((ArrayList<?>) resultObj).get(0)).isEmpty() && 
                 ((ArrayList<?>)((ArrayList<?>) resultObj).get(0)).get(0) instanceof String) {
            
            ArrayList<ArrayList<String>> queryResults = (ArrayList<ArrayList<String>>) resultObj;
            consoleArea.append("查询成功返回 " + (queryResults.size() -1) + " 行数据。\n"); // -1 for header row
            consoleArea.append("执行完成，耗时: " + lastExecutionTime + "ms\n");
            showQueryResult(command, queryResults);
            selectResultTab("查询结果 - "); // Select the new query result tab

        // Check for DESCRIBE results (List of String[])
        } else if (resultObj instanceof List && 
                   !((List<?>) resultObj).isEmpty() && 
                   ((List<?>) resultObj).get(0) instanceof String[]) {
            // This is the path for DESCRIBE results, ensure isErrorStringList already handled specific error format
            List<String[]> tableInfo = (List<String[]>) resultObj;
            String tableTitle = extractTableNameFromDescribe(command, 
                                                             session != null ? session.getCurrentDatabaseName() : "", 
                                                             session != null ? session.getCurrentUser() : "");
            if (tableTitle == null || tableTitle.equals(command)) tableTitle = "表结构: " + command.split("\\s+")[1];
            
            consoleArea.append("获取表 '" + tableTitle + "' 结构成功。\n");
            consoleArea.append("执行完成，耗时: " + lastExecutionTime + "ms\n");
            showTableInfo(tableInfo, tableTitle);
            selectResultTab("表结构: "); // Select the new table info tab

        } else if (resultObj instanceof String) {
            // Standard DDL/DML string results or errors from UICommandProcessor
            consoleArea.append((String) resultObj + "\n");
            consoleArea.append("执行完成，耗时: " + lastExecutionTime + "ms\n");
        } else if (resultObj == null) {
             consoleArea.append("命令执行未返回任何结果。\n");
             consoleArea.append("执行完成，耗时: " + lastExecutionTime + "ms\n");
        }else {
            // Fallback for unknown result types
            consoleArea.append("未知结果类型: " + resultObj.getClass().getName() + "\n");
            consoleArea.append(resultObj.toString() + "\n");
            consoleArea.append("执行完成，耗时: " + lastExecutionTime + "ms\n");
        }
        // Ensure status bar is updated after any execution
        updateStatusBar();
    }

}